﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using ProgNetComponentsDx.Options;
using System.Net;
using System.Data;
using System.Diagnostics;
using ProgNetComponents.Data.SqlCe;
using ProgNetComponents.Classes;
using System.Threading;
using System.IO;
using ProgNetComponentsDx.Browsers;
using System.Windows.Forms;
using System.Threading.Tasks;
using ProgNetComponentsDx.Forms;
using ProgNetComponentsDx.Controls;

namespace BuildHelper.Setup.Srodowiska
{
    public class Tools
    {
        private class GetEnvsTask
        {
            private object listSynch = new object();
            private static bool SkipEnvType
            {
                get { return OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Setup_Group.Definicje_Group.Srodowiska.SkipEnvType); }
            }

            #region Envs from SS
            private class EToolsPatterns
            {
                public static string RowPattern = "(<tr[^>]*>.*?</tr>)";
                public static string FullRowPattern = "<td[^>]*>(.*?)</td>\\s*<td[^>]*>(.*?)</td>\\s*<td[^>]*>(.*?)</td>\\s*<td[^>]*>\\s*Gene:([\\.0-9]*)\\s*[^<]*</td>"
                    + "\\s*<td>.*(http.*GcmWebServices)\\s*(</a>\\s*)?</td>\\s*<td[^>]*>(.*?)</td>";
                public static string FullRowPatternForEnv(string env)
                {
                    return "<td[^>]*>(" + env +")</td>\\s*<td[^>]*>(.*?)</td>\\s*<td[^>]*>(.*?)</td>\\s*<td[^>]*>\\s*Gene:([\\.0-9]*)\\s*[^<]*</td>"
                     + "\\s*<td>.*(http.*GcmWebServices)\\s*(</a>\\s*)?</td>\\s*<td[^>]*>(.*?)</td>";
                }
                /*
                 * 1 - env
                 * 2 - host
                 * 3 - user
                 * 4 - version
                 * 5 - url
                 * 7 - status
                 * */

                public static EnvData GetEnvData(string SingleEnvMask, string r)
                {
                    EnvData d = null;
                    Dictionary<int, string> dic = r.GetFirstMatch(SingleEnvMask, new int[] { 1, 2, 3, 4, 5, 7 });
                    if (dic != null && dic.Count > 0)
                    {
                        if (dic[1].IsNotNull() && dic[2].IsNotNull() && dic[5].IsNotNull())
                        {
                            d = new EnvData();
                            d.EnvName = dic[1];
                            d.Host = dic[2];
                            d.Url = dic[5];
                            d.Port = dic[5].GetFirstMatch(":(\\d+)/");
                            d.Wersja = dic[4];
                            d.Dziala = dic[7].XMatch("run");
                            d.Processed = true;
                            d.User = dic[3];
                        }
                    }
                    return d;
                }
            }
            #endregion
            #region Envs from SS
            private const string RowPattern = "(<tr[^>]*>.*?</tr>)";

            private const string RowNo = "<td[^>]*>.*?</td>";
            private const string RowHost = "<td[^>]*>(.*?)</td>";//1
            private const string RowUser = "<td[^>]*>(.*?)</td>";//2
            private const string RowEnv = "<td[^>]*><b>(.*?)</b></td>";//3
            private const string RowEnv2 = "<td[^>]*>(.*?)</td>";//4
            private const string RowVer = "<td[^>]*>(.*?)</td>";//5
            private const string RowVer2 = "<td[^>]*>.*?</td>";
            private const string RowBlank = "<td[^>]*>.*?</td>";
            private const string RowWs = "<td[^>]*><a [^>]*href=[\"\'](.*?)(index\\.jsp)?\\?a&login=sccadmin&pass=sccadmin&submitLogin=Login[\"\']";
        
            #endregion

            #region Envs from SU
            private const string EnvPattern = "(<h2[^>]*>(.*?)</h2>\\s*<table[^>]*>.*?</table>)";
            private const string EnvName = "<h2[^>]*>(.*?)</h2>";
            private const string EnvDataPattern = "<tr[^>]*>\\s*<td[^>]*>\\s*<a[^>]*href=['\"]([^'\"]*)['\"]>({APPS})<.*?</tr>";
            private string EnvAppMask = "";
            private static string GetAppMask()
            {
                string str = "";
                foreach (string s in WebApps.GetWebApps())
                {
                    str = str.AppendString("|");
                    str += "(" + s + ")";
                }
                return str;
            }
            private static EnvData GetEnvDataFromSU(string envName, string url)
            {
                EnvData e = new EnvData();
                e.EnvName = envName;
                ExtendedWebClient wc = null;
                try
                {
                    if (url.IsNullOrEmpty())
                    {
                        url = GetUrlForEnv(envName);
                    }
                    wc = new ExtendedWebClient();
                    wc.Timeout = OptionCache.GetOptionValue(Init.InitFormOptionNames.Setup_Group.Definicje_Group.Srodowiska.ActivityTimeout).AsInt(3000);
                    if (url.StartsWith("scc"))
                        url = url.XReplace("^scc", "http");
                    if (!TryGetData(envName, url, e, wc))
                    {
                        if (OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Setup_Group.Definicje_Group.Srodowiska.DoubleCheck))
                        {
                            wc.Timeout *= 2;
                            TryGetData(envName, url, e, wc);
                        }
                    }
                }
                catch (Exception ex)
                {
                    ex.LogInternal("envName: " + envName + "; Url: " + url);
                }
                finally
                {
                    try { wc.Dispose(); }
                    catch { }
                }
                return e;
            }
            private static bool TryGetData(string envName, string url, EnvData e, ExtendedWebClient wc)
            {
                bool result = false;
                try
                {
                    string s = wc.DownloadString(url);
                    string appurl = s.GetFirstMatch("<url>(.*?)</?url>");
                    e.Wersja = s.GetFirstMatch("<version>(.*?)</?version>");
                    foreach (string sys in WebApps.Systems)
                        appurl = appurl.XReplace("/" + sys + "/", "/gcm/");

                    appurl = appurl.XReplace("/ws", "/GcmWebServices");
                    appurl = appurl.XReplace("/Soft\\w*/?$", "/GcmWebServices");
                    e.Url = appurl;
                    string hostport = appurl.GetFirstMatch(".*?://([^/]*)/");
                    if (hostport.Contains(":"))
                    {
                        e.Host = hostport.GetFirstMatch("(.*):");
                        e.Port = hostport.GetFirstMatch(":(.*)");
                    }
                    else
                    {
                        e.Host = hostport;
                    }
                    List<string> list = envName.GetMatches("([a-zA-Z0-9]+)");
                    string telnetUser = "";
                    if (list.Count > 0)
                        telnetUser = list[list.Count - 1].GetFirstMatch("(D?[0-9]+)");
                    if (telnetUser.IsNotNull())
                        telnetUser += "scc";
                    e.User = telnetUser.ToLower();

                    e.Dziala = CheckUrl(e.Url, wc);
                    e.Processed = true;
                    result = true;
                }
                catch (System.Net.WebException)
                {
                    //ignore
                }
                catch (Exception ex)
                {
                    ex.LogInternal("envName: " + envName + "; url: " + url);
                }
                return result;
            }
       
            #endregion
           
            public GetEnvsTask()
            {
                List = new Dictionary<string, EnvData>();
            }

            public BackgroundControlBase BackgroundForm { get; set; }
            public Dictionary<string, EnvData> List { get; set; }
            public UpdateAllEnvInfo UpdateInfo { get; set; }
            private List<string> Envs { get; set; }

            private string Mask { get; set; }
            private string SingleEnvMask { get; set; }
            
            public string Source
            {
                get;
                set;
            }
            private int MaxThreads
            {
                get;
                set;
            }

            public void GetEnvs(string env = "")
            {
                InitSettings(env);
                ParallelOptions op = new ParallelOptions { MaxDegreeOfParallelism = MaxThreads };
                Parallel.ForEach<string>(Envs, op, GetEnvData);
            }

            private void InitSettings(string envName)
            {
                string url = string.Empty;
                string rowPattern=string.Empty;
                MaxThreads = OptionCache.GetOptionValue(Init.InitFormOptionNames.Setup_Group.Definicje_Group.Srodowiska.MaxThreads).AsInt(1);

                switch (Source)
                {
                    case EnvSource.SoftSystem:
                        url = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Setup_Group.URL.SrodowiskaSS);
                        rowPattern = RowPattern;
                        if (envName.IsNull())
                            SingleEnvMask = RowNo + RowHost + RowUser + RowEnv + RowEnv2 + RowVer + RowVer2 + RowBlank + RowWs;
                        else
                        {
                            string env1 = envName.GetFirstMatch("([^ ]*)");
                            string env2 = envName.GetFirstMatch("[^ ]* (.*)");
                            SingleEnvMask = RowNo + RowHost + RowUser + RowEnv.Replace("(.*?)", "(" + env1 + ")") + RowEnv2.Replace("(.*?)", "(" + env2 + ")") + RowVer + RowVer2 + RowBlank + RowWs;
                        }
                        break;
                    case EnvSource.SoftUpdate:
                        url = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Setup_Group.URL.Srodowiska);
                        rowPattern = EnvPattern;
                        if (envName.IsNull())
                            SingleEnvMask = EnvPattern;
                        else
                            SingleEnvMask = EnvPattern.Replace("<h2[^>]*>(.*?)</h2>", "<h2[^>]*>(" + envName + ")</h2>");

                        EnvAppMask = EnvDataPattern.Replace("{APPS}", GetAppMask());
                        break;
                    case EnvSource.ETools:
                        url = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Setup_Group.Definicje_Group.Srodowiska.SrodowiskaETools);
                        rowPattern = EToolsPatterns.RowPattern;
                        if (envName.IsNull())
                            SingleEnvMask = EToolsPatterns.FullRowPattern;
                        else
                        {
                            string env1 = envName.GetFirstMatch("([^ ]*)");
                            string env2 = envName.GetFirstMatch("[^ ]* (.*)");
                            SingleEnvMask = EToolsPatterns.FullRowPatternForEnv(env2);
                        }
                        break;
                }
                using (ExtendedWebClient wc = new ExtendedWebClient())
                {
                    if (url.IsNotNull())
                    {
                        string envs = wc.DownloadString(url);
                        if (envs.IsNotNull())
                        {
                            Envs = envs.GetMatches(rowPattern,1, System.Text.RegularExpressions.RegexOptions.IgnoreCase| System.Text.RegularExpressions.RegexOptions.Singleline);
                        }
                    }
                }
                if (Envs != null && envName.IsNotNull())
                {
                    string sEnv = string.Empty;
                    foreach (string s in Envs)
                    {
                        if (s.XMatch(SingleEnvMask))
                        {
                            sEnv = s;
                            break;
                        }
                    }
                    Envs.Clear();
                    if (sEnv.IsNotNull())
                        Envs.Add(sEnv);
                }
                if (BackgroundForm != null)
                {
                    BackgroundForm.MaxProgress = Envs.Count;
                }
                if (UpdateInfo != null)
                {
                    UpdateInfo.MaxEnvs = Envs.Count;
                }
            }
            
            private void GetEnvData(string r)
            {
                try
                {
                    if (BackgroundForm != null)
                    {
                        if (BackgroundForm.IsCanceling)
                            return;

                        BackgroundForm.Progress++;
                        BackgroundForm.LabelText = BackgroundForm.Progress + "/" + BackgroundForm.MaxProgress;
                    }
                    if (UpdateInfo != null)
                    {
                        Task t = Task.Factory.StartNew(() => {
                            UpdateInfo.ProcessedEnvs++; 
                            UpdateInfo.UpdateForm();
                        });
                    }

                    EnvData d = null;
                    switch (Source)
                    {
                        case EnvSource.SoftSystem:
                            d = GetSSEnvData(r);
                            break;
                        case EnvSource.SoftUpdate:
                            d = GetSUEnvData(r);
                            break;
                        case EnvSource.ETools:
                            d = EToolsPatterns.GetEnvData(SingleEnvMask, r);
                            break;
                    }
                    if (d != null)
                    {
                        lock (listSynch)
                        {
                            if (d.EnvName.IsNotNull() && !List.ContainsKey(d.EnvName))
                            {
                                List.Add(d.EnvName, d);
                            }
                        }
                    }
                }
                catch { }
            }
            private  EnvData GetSUEnvData(string r)
            {
                EnvData e = new EnvData();
                string envName = r.GetFirstMatch(EnvName);
                if (SkipEnvType)
                    envName = envName.GetFirstMatch("(.* )?(.*)", 2);
                ExtendedWebClient wc = null;
                try
                {
                    List<string> envData = r.GetMatches(EnvAppMask);

                    if (envData != null && envData.Count > 0)
                    {
                        foreach (string ed in envData)
                        {
                            e = GetEnvDataFromSU(envName, ed);
                            if (e != null)
                                break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    ex.LogInternal("envName: " + envName);
                }
                finally
                {
                    try { wc.Dispose(); }
                    catch { }
                }
                return e;
            }

            private EnvData GetSSEnvData(string r)
            {
                EnvData d = null;
                Dictionary<int, string> dic = r.GetFirstMatch(SingleEnvMask, new int[] { 1, 2, 3, 4, 5, 6 });
                if (dic != null && dic.Count > 0)
                {
                    if (dic[1].IsNotNull() && dic[3].IsNotNull() && dic[6].IsNotNull())
                    {
                        d = new EnvData();
                        string envName = string.Empty;
                        if (SkipEnvType)
                            d.EnvName = dic[3];
                        else
                            d.EnvName = dic[4] + " " + dic[3];
                        d.Host = dic[1];
                        d.Url = dic[6];
                        d.Port = dic[6].GetFirstMatch(":(\\d+)/");
                        d.Wersja = dic[5];
                        d.Dziala = r.XMatch("<tr bgcolor");
                        d.Processed = true;
                        d.User = dic[2];
                    }
                }
                return d;
            }

            
        }

        public static class WebApps
        {
            
            public const string SoftMol = "SoftMol";
            public const string SoftBioChem = "SoftBioChem";
            public const string SoftCtg = "SoftCtg";
            public const string SoftFlw = "SoftFlw";
            public const string SoftHLA = "SoftHLA";
            public const string SoftPreanalytical = "SoftPreanalytical";
            public const string SoftPathDx = "SoftPathDx";
            public const string SoftDxPath = "SoftDxPath";

            static string[] webAppsArray = new string[]
            {
                SoftBioChem,
                SoftCtg,
                SoftDxPath,
                SoftFlw,
                SoftHLA,
                SoftMol,
                SoftPathDx,
                SoftPreanalytical
            };
            public static string[] GetWebApps()
            {
                return webAppsArray;
            }
            static string[] systems = new string[]
            {
                "bio",
                "ctg",
                "dxp",
                "flw",
                "hla",
                "mol",
                "acc"
            };
            public static string[] Systems
            {
                get { return systems; }
            }
        }
        
        #region common
        public static EnvData GetEnvData(BackgroundControlBase form, string envName)
        {
            Dictionary<string, EnvData> dic = GetEnvs(form, envName, null);
            if (dic != null && dic.Count > 0)
            {
                if (dic.ContainsKey(envName))
                    return dic[envName];
            }
            return null;
        }
        public static bool UpdateEnvs(BackgroundControlBase form, SrodowiskaDataSet ds, string envName = "")
        {
            return UpdateEnvs(form, ds, envName, (UpdateAllEnvInfo)null);
        }
        private static Dictionary<string, EnvData> GetEnvs(BackgroundControlBase form, string envName, UpdateAllEnvInfo a)
        {
            string op = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Setup_Group.Definicje_Group.Srodowiska.EnvSource);

            GetEnvsTask t = new GetEnvsTask();
            t.BackgroundForm = form;
            t.Source = op;
            t.UpdateInfo = a;
            t.GetEnvs(envName);
            return t.List;
        }

        private static bool UpdateEnvs(BackgroundControlBase form, SrodowiskaDataSet ds, string envName, UpdateAllEnvInfo a)
        {
            bool result = true;
            Dictionary<string, EnvData> list = GetEnvs(form, envName, a);
            if (list != null)
                result = UpdateEnvs(form, ds, list, envName);
            else
                result = false;
            return result;
        }
        private static bool UpdateEnvs(BackgroundControlBase form, SrodowiskaDataSet ds, Dictionary<string, EnvData> envs, string singleEnv)
        {
            bool result = true;
            try
            {
                if (ds == null)
                {
                    ds = new SrodowiskaDataSet();
                    using (SqlCeDataManager m = new SqlCeDataManager())
                    {
                        m.AutoLogExceptions = true;
                        m.AddTableDef(ds.STP_SRODOWISKA, "SELECT * FROM STP_SRODOWISKA WHERE STP_SR_WLASNE = 0");
                        if (m.FillDataSet(ds))
                        {
                            if (UpdateDs(ds, envs, false, singleEnv))
                            {
                                if (ds.HasChanges())
                                {
                                    result = m.UpdateDataSet(ds);
                                    if (result)
                                    {
                                        BrowserCache.RefreshCacheForTable("STP_SRODOWISKA");
                                        if (Srodowiska.FormSrodowiska.Instance != null)
                                        {
                                            Srodowiska.FormSrodowiska.Instance.EnvsModified();
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            result = false;
                        }
                    }
                }
                else
                {
                    result = UpdateDs(ds, envs, true, singleEnv);
                }
            }
            catch (Exception ex)
            {
                result = false;
                ex.Log();
            }
            return result;
        }

        private delegate bool UpdateDsHandler(SrodowiskaDataSet ds, Dictionary<string, EnvData> list, bool invoke, string singleEnv);
        private static bool UpdateDs(SrodowiskaDataSet ds, Dictionary<string, EnvData> list, bool invoke, string singleEnv)
        {
            if (invoke && FormMain.Instance.InvokeRequired)
            {
                return FormMain.Instance.Invoke(new UpdateDsHandler(UpdateDs), ds, list, invoke, singleEnv).AsBool();
            }
            bool result = true;
            SqlCeDataManager m =null;
            try
            {
                if ((list.Count > 0 || singleEnv.IsNotNull()) 
                    && OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Setup_Group.Definicje_Group.Srodowiska.KasujNieistniejace))
                {
                    string q = "STP_SR_WLASNE = 0";
                    if (singleEnv.IsNotNull())
                        q += " AND STP_SR_NAZWA = " + singleEnv.EscapeSql();
                    DataRow[] rows = ds.STP_SRODOWISKA.Select(q, null, DataViewRowState.CurrentRows);
                    bool delDB = OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Setup_Group.Definicje_Group.Srodowiska.KasujBazePrzyKasowaniuSrodowiska);
                    if (delDB)
                    {
                        m = new SqlCeDataManager();
                        m.AutoLogExceptions = true;
                        m.AutoCommit = true;
                    }
                    NamedObject obj = new NamedObject("@NAZWA", "");
                    string env;
                    foreach (DataRow r in rows)
                    {
                        env = r["STP_SR_NAZWA"].ToString();
                        if (singleEnv.IsNull() || singleEnv == env)
                        {
                            if (!list.ContainsKey(env))
                                r.Delete();
                            if (delDB)
                            {
                                if (BazyDanych.FormBazyDanych.Instance != null)
                                {
                                    try { BazyDanych.FormBazyDanych.Instance.DeleteEnv(env); }
                                    catch { }
                                }
                                else
                                {
                                    obj.Value = env;
                                    m.ExecuteNonQuery("DELETE FROM STP_BAZY_DANYCH WHERE STP_BD_NAZWA = @NAZWA", obj);
                                }
                            }
                        }
                    }
                }
                DataRow row;
                foreach (KeyValuePair<string, EnvData> kvp in list)
                {
                    row = ds.STP_SRODOWISKA.SelectFirstRow("STP_SR_NAZWA = " + kvp.Key.EscapeSql(), null, DataViewRowState.CurrentRows);
                    if (row == null)
                    {
                        row = ds.STP_SRODOWISKA.NewRow();
                        ds.STP_SRODOWISKA.Rows.Add(row);
                    }
                    row.SetColVal("STP_SR_NAZWA", kvp.Key);
                    row.SetColVal("STP_SR_HOST", kvp.Value.Host);
                    row.SetColVal("STP_SR_PORT", kvp.Value.Port);
                    row.SetColVal("STP_SR_URL", kvp.Value.Url);
                    row.SetColVal("STP_SR_DZIALA", kvp.Value.Dziala);
                    row.SetColVal("STP_SR_WERSJA", kvp.Value.Wersja);
                    row.SetColVal("STP_SR_WLASNE", false);
                    row.SetColVal("STP_SR_DATA_AKTUALIZACJI", DateTime.Now);
                    row.SetColVal("STP_SR_USER", kvp.Value.User);
                }
            }
            catch (Exception ex)
            {
                ex.Log();
            }
            finally
            {
                if (m != null)
                    m.Dispose();
            }
            return result;
        }
        #endregion

        private static string GetUrlForEnv(string envName)
        {
            string result = "";
            try
            {
                string url = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Setup_Group.URL.Srodowiska);
                WebClient w = GlobalTools.GetWebClient();
                string site = w.DownloadString(url);
                string[] webapps = WebApps.GetWebApps();

                string mask = "<h2>([^<]*)</h2>\\s*<table[^>]*>(.*?)</table>";
                if (envName.IsNotNull())
                {
                    int idx = site.IndexOf(envName, 0, StringComparison.CurrentCultureIgnoreCase);
                    if (idx > -1)
                    {
                        idx -= 10;
                        if (idx > 0)
                            site = site.SubstringSafe(idx, 5000);
                    }
                }
                Dictionary<int, string> dic = site.GetFirstMatch(mask, new int[] { 1, 2 }, System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.Singleline);

                string getConfigMask = "<td>\\s*<a\\s+href=['\"]([^'\"]*)['\"]>\\s*{0}\\s*<";
                string getUrl = "";
                if (dic != null)
                {
                    string tmpMask = "";
                    if (envName.IsNotNull() && dic[1] == envName)
                    {
                        getUrl = "";
                        foreach (string s in webapps)
                        {
                            tmpMask = getConfigMask.XFormat(s);
                            getUrl = dic[2].GetFirstMatch(tmpMask);
                            if (getUrl.IsNotNullOrEmpty())
                            {
                                result = getUrl;
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ex.LogDebug();
            }
            return result;
        }
        
        public static bool CheckUrl(string url, ExtendedWebClient wc = null)
        {
            bool disp = false;
            if (wc == null)
            {
                wc = new ExtendedWebClient();
                disp = true;
            }
            bool dziala = false;
            try
            {
                string tmp = wc.DownloadString(url);

                if (!tmp.XMatch("Error \\d+"))//Error 404, Error 500
                    dziala = true;
            }
            catch { }
            finally
            {
                if (disp)
                    wc.Dispose();
            }

            return dziala;
        }
        public class EnvData
        {
            public string Url { get; set; }
            public string Port { get; set; }
            public string Host { get; set; }
            public string Wersja { get; set; }
            public bool Dziala { get; set; }
            public bool Processed { get; set; }
            public string EnvName { get; set; }
            public string User { get; set; }
        }

        private static void UpdateEnv(params EnvData[] envs)
        {
            try
            {
                if (envs != null)
                {
                    SqlCeDataManager m = new SqlCeDataManager();
                    try
                    {
                        m.AutoLogExceptions = true;
                        m.AutoCommit = true;
                        SrodowiskaDataSet s = new SrodowiskaDataSet();
                        m.AddTableDef(s.STP_SRODOWISKA, "SELECT * FROM STP_SRODOWISKA WHERE STP_SR_NAZWA = @NAZWA");
                        foreach (EnvData e in envs)
                        {
                            if (Srodowiska.FormSrodowiska.Instance != null)
                            {
                                if (e.Url.IsNotNull())
                                {
                                    try { Srodowiska.FormSrodowiska.Instance.MergeRow(e); }
                                    catch { }
                                }
                            }
                            else
                            {
                                s.Clear();
                                m.FillDataSet(s, new NamedObject("@NAZWA", e.EnvName));

                                DataRow r = s.STP_SRODOWISKA.SelectFirstRow();
                                bool modified = true;

                                if (r == null)
                                {
                                    r = s.STP_SRODOWISKA.NewRow();
                                    r["STP_SR_NAZWA"] = e.EnvName;
                                    s.STP_SRODOWISKA.Rows.Add(r);
                                    modified = false;
                                }

                                modified |= r.SetColVal("STP_SR_DZIALA", e.Dziala);
                                modified |= r.SetColVal("STP_SR_HOST", e.Host);
                                if (e.Port.IsNotNull())
                                    modified |= r.SetColVal("STP_SR_PORT", e.Port);
                                else
                                    modified |= r.SetColVal("STP_SR_PORT", DBNull.Value);
                                modified |= r.SetColVal("STP_SR_WLASNE", false);
                                modified |= r.SetColVal("STP_SR_URL", e.Url);
                                modified |= r.SetColVal("STP_SR_WERSJA", e.Wersja);
                                r.SetColVal("STP_SR_DATA_AKTUALIZACJI", DateTime.Now);
                            }
                            m.UpdateDataSet(s);
                        }
                    }
                    finally
                    {
                        m.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                ex.LogError();
            }
        }

        #region Open URL
        private class OpenUrlThreadInfo
        {
            public OpenUrlThreadInfo( DataRow r)
            {
                Row = r;
            }
            public DataRow Row
            {
                get;
                set;
            }
        }
        public static void OpenUrl(string url)
        {
            try
            {
                string url2 = url.AsString().TrimEnd('/') + "/?login=sccadmin&pass=sccadmin&submitLogin&a=";
                if (OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Setup_Group.Definicje_Group.Srodowiska.OpenTrace))
                    url2 += "tr";
                System.Diagnostics.Process.Start(url2);
            }
            catch (Exception ex)
            {
                FormMain.Instance.ShowErrorDialog("Wystąpił proble w otwieraniu adresu URL: " +url);
                ex.Log();
            }
        }
        public static string GetOnenId(string env){
            return "OTW_URL_"+env;
        }
        private static void OpenUrlTh(object arg)
        {
            OpenUrlThreadInfo a = arg as OpenUrlThreadInfo;
            if (a != null)
            {
                string envName = a.Row["STP_SR_NAZWA"].AsString();

                try
                {
                    string op = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Narzedzia.OdswiezajSrodowiskoPrzyOtwarciu);
                    string url = a.Row["STP_SR_URL"].AsString();
                    bool openOrg = true;
                    EnvData e;
                    bool doRefresh = false;
                    switch (op)
                    {
                        case "Z":
                            doRefresh = true;
                            break;
                        case "NR":
                            if (!CheckUrl(url))
                                doRefresh = true;
                            break;
                        case "A":
                            if (FormMain.Instance.ShowDxYNQuestionDialog("Odświeżyć środowisko?") == System.Windows.Forms.DialogResult.Yes)
                                doRefresh = true;
                            break;
                        case "ANR":
                            if (!CheckUrl(url))
                            {
                                if (FormMain.Instance.ShowDxYNQuestionDialog("Środowisko nie odpowiada.\nChcesz je odświeżyć?") == System.Windows.Forms.DialogResult.Yes)
                                    doRefresh = true;
                            }
                            break;
                    }
                    if (doRefresh)
                    {
                        e = GetEnvData(null, envName);
                        if (e != null && e.Processed)
                        {
                            if (e.Url.IsNotNull())
                            {
                                UpdateEnv(e);
                                openOrg = false;
                                OpenUrl(e.Url);
                            }
                        }
                    }
                    if (openOrg)
                    {
                        OpenUrl(url);
                    }
                }
                finally
                {
                    try
                    {
                        FormMain.CloseAlertById(GetOnenId(envName));
                    }
                    catch { }
                }
            }
        }
        public static void OpenUrl(DataRow row)
        {
            Thread t = new Thread(new ParameterizedThreadStart(OpenUrlTh));
            t.Start(new OpenUrlThreadInfo(row));
        }
        #endregion

        #region Open console
        public static void OpenConsole(DataRow row)
        {
            Thread t = new Thread(new ParameterizedThreadStart(OpenConsoleTh));
            t.Start(new OpenUrlThreadInfo(row));
        }
        public static string GetOnenConsoleId(string env)
        {
            return "OTW_HOST_" + env;
        }

        private static void OpenConsoleTh(object arg)
        {
            OpenUrlThreadInfo a = arg as OpenUrlThreadInfo;
            if (a != null)
            {
                string envName = a.Row["STP_SR_NAZWA"].AsString();

                try
                {
                    string telnetUser = a.Row["STP_SR_USER"].AsString(); ;

                    string url = a.Row["STP_SR_URL"].AsString();
                    string host = a.Row["STP_SR_HOST"].AsString();
                    if (telnetUser.IsNull())
                    {
                        List<string> list = envName.GetMatches("([a-zA-Z0-9]+)");

                        if (list.Count > 0)
                            telnetUser = list[list.Count - 1].GetFirstMatch("(D?[0-9]+)");
                        if (telnetUser.IsNotNull())
                            telnetUser += "scc";
                        telnetUser = telnetUser.ToLower();
                    }
                    TelnetConnection c = null;
                    

                    string refresh = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Narzedzia_Group.TelnetConsole.Odswiezaj);
                    bool sendUser = OptionCache.GetOptionBoolValue(Init.InitFormOptionNames.Narzedzia_Group.TelnetConsole.SendUserName);

                    bool openOrg = true;
                    EnvData e;
                    Process p = null;
                    bool hostOk = true;
                    bool doRefresh = false;
                    switch (refresh)
                    {
                        case "Z":
                            doRefresh = true;
                            break;
                        case "NR":
                            try
                            {
                                c = new TelnetConnection(host, 23);
                            }
                            catch { doRefresh = true; }
                            
                            break;
                        case "A":
                            if (FormMain.Instance.ShowDxYNQuestionDialog("Odświeżyć środowisko?") == System.Windows.Forms.DialogResult.Yes)
                                doRefresh = true;
                            break;
                        case "ANR":
                            try
                            {
                                c = new TelnetConnection(host, 23);
                            }
                            catch { hostOk = false; }
                            if (!hostOk)
                            {
                                if (FormMain.Instance.ShowDxYNQuestionDialog("Host " + host + " nie odpowiada.\nChcesz odświeżyć środowisko?") == System.Windows.Forms.DialogResult.Yes)
                                    doRefresh = true;
                            }
                            break;
                    }
                    if (doRefresh)
                    {
                        e = GetEnvData(null, envName);
                        if (e!=null && e.Host.IsNotNull() && e.Url.IsNotNull())
                        {
                            UpdateEnv(e);
                            openOrg = false;
                            if (host != e.Host)
                                FormMain.ShowWarningAlert("Zmieniony host dla " + envName + Constants.NewLineLinux + "Był: " + host + ", jest: " + e.Host);
                            p = OpenConsole(e.Host, telnetUser);
                        }
                    }
                    if (openOrg)
                    {
                        p = OpenConsole(host, telnetUser);
                    }
                    if (p != null && sendUser)
                    {
                        Thread t = new Thread(new ParameterizedThreadStart(SendUser));
                        OpenConsoleProcessInfo arg2 = new OpenConsoleProcessInfo(p, telnetUser);
                        t.Start(arg2);
                    }
                }
                finally
                {
                    try
                    {
                        FormMain.CloseAlertById(GetOnenConsoleId(envName));
                    }
                    catch { }
                }
            }
        }
        private static void SendUser(object arg)
        {
            OpenConsoleProcessInfo p = arg as OpenConsoleProcessInfo;
            if (p != null)
            {
                try
                {
                    while (User32.GetForegroundWindow() != p.Process.MainWindowHandle)
                    {
                        while (User32.GetForegroundWindow() != p.Process.MainWindowHandle)
                        {
                            Thread.Sleep(10);
                        }
                        if (User32.GetForegroundWindow() == p.Process.MainWindowHandle)
                        {
                            WindowsInput.InputSimulator.SimulateTextEntry(p.UserName);
                            WindowsInput.InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.RETURN);
                            break;
                        }
                    }
                }
                finally
                {
                   
                }
            }
        }
        private class OpenConsoleProcessInfo
        {
            public OpenConsoleProcessInfo(Process p, string u)
            {
                Process = p;
                UserName = u;
            }
            public Process Process
            {
                get;
                set;
            }
            public string UserName
            {
                get;
                set;
            }
        }
        private static Process  OpenConsole(string host, string telnetUser)
        {
            string program = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Narzedzia_Group.TelnetConsole.TelnetProgram);
            string param = OptionCache.GetOptionStringValue(Init.InitFormOptionNames.Narzedzia_Group.TelnetConsole.Parameters);

            Process p = null;
            try
            {
                if (File.Exists(program))
                {
                    param = param.Replace("[HOST]", host);
                    param = param.Replace("[USER]", telnetUser);
                    p = Process.Start(program, param);
                }
                else
                {
                    FormMain.Instance.ShowErrorDialog("Błąd otwierania konsoli. Nie można odnaleźć programu: \n" +
                        program.AddDoubleQuotes());
                }
            }
            catch { }
            return p;
        }
        #endregion

        #region Update env
        public static void UpdateEnv(string envName)
        {
            Thread t = new Thread(new ParameterizedThreadStart(UpdateEnvTh));
            t.Start(envName);
        }
        
        private static void UpdateEnvTh(object obj)
        {
            string envName = obj.AsString();
            UpdateEnvs(null, null, envName, null);
            FormMain.CloseAlertById(GetUpdateEnvId(envName));
        }
       
        public static string GetUpdateEnvId(string env)
        {
            return "UPD_ENV " + env;
        }
        #endregion

        #region Update all envs
        static int updEnvId = 0;
        private class UpdateAllEnvInfo
        {
            public UpdateAllEnvInfo(int n, DataRow r)
            {
                Index = n;
                Row = r;
                IsInThread = true;
            }
            public DataRow Row
            {
                get;
                private set;
            }
            public int Index
            {
                get;
                set;
            }
            public int MaxEnvs
            {
                get;
                set;
            }
            public int ProcessedEnvs
            {
                get;
                set;
            }
            public void UpdateForm()
            {
                FormMain.UpdateAlertText(GetUpdateAllEnvsId(Index), "Uaktualnianie środowisk\n" + ProcessedEnvs.ToString() + "/" + MaxEnvs);
            }
            public bool IsInThread { get; set; }
        }
        public static void UpdateAllEnvs(bool showInfo, DataRow row)
        {
            UpdateAllEnvs(showInfo, row, true);
        }
        public static void UpdateAllEnvs(bool showInfo, DataRow row, bool inThread)
        {
            if (showInfo)
            {
                string msg = "Uaktualnianie środowisk";
                System.Drawing.Image img = FormMain.Instance.MenuControl.commonImageCollectionFull1.Images[86];
                FormMain.AlertInfo a = new FormMain.AlertInfo(true, GetUpdateAllEnvsId());
                FormMain.ShowAlert(msg, img, a);
            }
            UpdateAllEnvInfo e = new UpdateAllEnvInfo(updEnvId, row);
            if (inThread)
            {
                Thread t = new Thread(new ParameterizedThreadStart(UpdateAllEnvsTh));
                t.Start(e);
                updEnvId++;
            }
            else
            {
                e.IsInThread = false;
                UpdateAllEnvsTh(e);
            }
        }

        public static string GetUpdateAllEnvsId()
        {
            return GetUpdateAllEnvsId(updEnvId);
        }
        private static string GetUpdateAllEnvsId(int i)
        {
            return "UPDATE_ENVS_"+i;
        }
        private static void UpdateAllEnvsTh(object arg)
        {
            UpdateAllEnvInfo a = arg as UpdateAllEnvInfo;
            if (a != null)
            {
                try
                {
                    UpdateEnvs(null, null, "", a);
                }
                catch (Exception ex)
                {
                    ex.Log();
                    FormMain.ShowErrorAlert("Wystąpił problem podczas pobierania środowisk");
                }
                finally
                {
                    FormMain.CloseAlertById(GetUpdateAllEnvsId(a.Index));
                }
            }
        }
        #endregion
    }

    public static class EnvSource
    {
        public const string SoftSystem = "SS";
        public const string SoftUpdate = "SU";
        public const string ETools = "ET";
    }
}